package com.authine.cloudpivot.ext.controller;

import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Api(value = "custom 接口", tags = "")
@RequestMapping("/bsjPoc")
@RestController
@Slf4j
public class BaoShiJiePocController extends BaseController {
    /**
     * 自动将经销商信息复制到评分汇总
     * @param objId
     */
    @RequestMapping("generateDealerScoreSummary")
    public String generateDealerScoreSummary(String objId) {
        log.info("自动将经销商信息复制到评分汇总");
        log.info("获取参数:objId={}", objId);
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject("DealerReviewTargetSettin", objId);
        if (bizObject == null) {
            log.info("业务对象获取失败");
        }
        //获取经销商明细
        List<Map<String, Object>> bbList = (List<Map<String, Object>>) bizObject.get("DealerKPI");
        //根据经销商明细生成评分汇总明细
        List<Map<String, Object>> summaryList = new ArrayList<>();
        if(bbList != null){
            for (Map<String, Object> dealerKPI : bbList){
                Map<String, Object> dealerScoreSummary = new HashMap();
                dealerScoreSummary.put("Dealername", dealerKPI.get("ShortText1589875357956"));
                dealerScoreSummary.put("Dealercode", dealerKPI.get("ShortText1589875367307"));
                dealerScoreSummary.put("Dealermanager", dealerKPI.get("Dealermanager"));
                dealerScoreSummary.put("parentId", bizObject.getId());
                dealerScoreSummary.put("id", UUID.randomUUID().toString().replace("-", ""));
                summaryList.add(dealerScoreSummary);
            }
        }
        bizObject.getData().put("DealerScoreSummary", summaryList);
        bizObjectFacade.saveBizObject(bizObject.getOwner().getId(), bizObject, true);
        log.info("自动将经销商信息复制到评分汇总-----success");
        return "执行成功";
    }

    /**
     * 更新排名
     * @param rate
     * @param objId
     * @param wid
     * @param isAdjust
     * @param category
     * @param jxsCode
     */
    @RequestMapping("updateRateAndRank")
    public String updateRateAndRank(BigDecimal rate, String objId, String wid, String isAdjust, String category, String jxsCode){
        log.info("获取参数:rate={},objId={},wid={},isAdjust={},category={},jxsCode={}",rate,objId,wid,isAdjust,category,jxsCode);
        if("否".equals(isAdjust) || StringUtils.isBlank(jxsCode)){
            log.info("参数不完整或者是否调整为否，直接结束");
            return "参数不完整或者是否调整为否，直接结束";
        }
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject("DealerScoreConfirm", objId);

        if (bizObject == null) {
            log.info("业务对象不存在");
            return "业务对象不存在";
        }

        // TODO: 获取流程数据及业务数据
        WorkflowInstanceModel wiModel = super.getWorkflowInstanceFacade().getWorkflowInstance(wid);
        WorkflowInstanceModel parentWiModel = null;//父流程
        if(wiModel != null){
            parentWiModel = super.getWorkflowInstanceFacade().getWorkflowInstance(wiModel.getParentId());
            if(parentWiModel == null){
                return "父流程对象不存在";
            }
        }
        //父流程业务对象
        BizObjectCreatedModel parentBizObjectModel = bizObjectFacade.getBizObject("DealerReviewTargetSettin", parentWiModel.getBizObjectId());
        if(parentBizObjectModel == null){
            return "主流程业务对象不存在";
        }

        // TODO:计算得分及排名
        countRankAndScore(bizObject, parentBizObjectModel, rate, category, jxsCode);
        //TODO:更新得分及排名
        bizObjectFacade.saveBizObject(bizObject.getOwner().getId(), bizObject, true);
        bizObjectFacade.saveBizObject(parentBizObjectModel.getOwner().getId(), parentBizObjectModel, true);
        return "执行成功";
    }

    /**
     * 计算评分汇总的总得分和总排名
     * @param objId
     */
    @RequestMapping("sumSummary")
    public void sumSummary(String objId) {
        log.info("计算评分汇总的总得分和总排名");
        log.info("获取参数:objId={}", objId);
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();

        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject("DealerReviewTargetSettin", objId);
        if (bizObject == null) {
            log.info("业务对象获取失败");
        }
        //根据经销商明细生成评分汇总明细
        List<Map<String, Object>> summaryList = (List<Map<String, Object>>)bizObject.get("DealerScoreSummary");
        //计算总得分和总排名
        countTotalScoreAndRank(summaryList);

        bizObjectFacade.saveBizObject(bizObject.getOwner().getId(), bizObject, true);
        log.info("计算评分汇总的总得分和总排名-----success");
    }


    //计算得分及排名
    private void countRankAndScore(BizObjectCreatedModel bizObject, BizObjectCreatedModel parentBizObjectModel, BigDecimal rate, String category, String jxsCode){
        List<Map<String, Object>> summaryList = (List<Map<String, Object>>)parentBizObjectModel.get("DealerScoreSummary");
        switch (category){
            case "CSV":
                //CSV率
                //更新主流程上经销商csv率
                summaryList.stream().forEach(item -> {
                    String dealercode = (String) item.get("Dealercode");
                    if(StringUtils.isNotBlank(dealercode) && dealercode.equals(jxsCode)){
                        //更新CSV率
                        item.put("CSVRate", rate);
                    }
                });

                //按csv率重新排名
                summaryList = summaryList.stream().sorted((objA, objB) -> {
                    // csv率越高，排名越靠前
                    BigDecimal csvA = Optional.of((BigDecimal) objA.get("CSVRate")).orElse(BigDecimal.ZERO);
                    BigDecimal csvB = Optional.of((BigDecimal) objB.get("CSVRate")).orElse(BigDecimal.ZERO);
                    return csvA.compareTo(csvB) >= 0 ? -1 : 1;
                }).collect(Collectors.toList());

                //获取评分细则
                List<Map<String, Object>> csvDetailList = (List<Map<String, Object>>)parentBizObjectModel.get("CSVRateDetail");
                //更新排名
                for (int i = 0; i < summaryList.size(); i ++){
                    if(i >= csvDetailList.size()){
                        //排名已用完
                        break;
                    }
                    //调整排名
                    Map<String, Object>map = summaryList.get(i);
                    map.put("CSVRanking", csvDetailList.get(i).get("Rank"));
                    map.put("CSVScore", csvDetailList.get(i).get("Score"));

                    if(jxsCode.equals(map.get("Dealercode"))){
                        //更新子流程经销商排名
                        bizObject.getData().put("CSVRate", rate);
                        bizObject.getData().put("CSVRanking", csvDetailList.get(i).get("Rank"));
                        bizObject.getData().put("CSVScore", csvDetailList.get(i).get("Score"));
                    }
                }
                break;
            case "PAS":
                //PAS率
                //更新主流程上经销商PAS率
                summaryList.stream().forEach(item -> {
                    String dealercode = (String) item.get("Dealercode");
                    if(StringUtils.isNotBlank(dealercode) && dealercode.equals(jxsCode)){
                        //更新PAS率
                        item.put("PASRate", rate);
                        //如果PAS率超过阈值，则得分和排名为0
                        if(rate.compareTo((BigDecimal) parentBizObjectModel.get("PASYZ")) >= 0){
                            item.put("PASRanking", BigDecimal.ZERO);
                            item.put("PASScore", BigDecimal.ZERO);
                        }
                    }
                });

                //按PAS率重新排名
                summaryList = summaryList.stream().sorted((objA, objB) -> {
                    // PAS率越低，排名越靠前
                    BigDecimal pasA = Optional.of((BigDecimal) objA.get("PASRate")).orElse(BigDecimal.ZERO);
                    BigDecimal pasB = Optional.of((BigDecimal) objB.get("PASRate")).orElse(BigDecimal.ZERO);
                    return pasA.compareTo(pasB) >= 0 ? 1 : -1;
                }).collect(Collectors.toList());

                //获取评分细则
                List<Map<String, Object>> pasDetailList = (List<Map<String, Object>>)parentBizObjectModel.get("PASDetail");
                //更新排名
                BigDecimal Ranking = null;
                BigDecimal Score = null;
                for (int i = 0; i < summaryList.size(); i ++){
                    //调整排名
                    Map<String, Object>map = summaryList.get(i);
                    if(((BigDecimal)map.get("PASRate")).compareTo((BigDecimal) parentBizObjectModel.get("PASYZ")) >= 0){
                        //超过阈值的，不计算排名
                        Ranking = BigDecimal.ZERO;
                        Score = BigDecimal.ZERO;
                    }else {
                        Ranking = (BigDecimal) pasDetailList.get(i).get("Ranking");
                        Score = (BigDecimal) pasDetailList.get(i).get("Score");
                        map.put("PASRanking", Ranking);
                        map.put("PASScore", Score);
                    }
                    //更新子流程
                    if(jxsCode.equals(map.get("Dealercode"))){
                        //更新子流程经销商排名
                        bizObject.getData().put("PASRate", rate);
                        bizObject.getData().put("PASRanking", Ranking);
                        bizObject.getData().put("PASScore", Score);
                    }
                }
                break;
            case "CRR":
                //CRR率
                //更新主流程上经销商CRR率
                summaryList.stream().forEach(item -> {
                    String dealercode = (String) item.get("Dealercode");
                    if(StringUtils.isNotBlank(dealercode) && dealercode.equals(jxsCode)){
                        //更新CRR率
                        item.put("CRRRate", rate);
                        //获取评分细则
                        List<Map<String, Object>> cRRDetailList = (List<Map<String, Object>>)parentBizObjectModel.get("CRRdetail");
                        //更新得分，根据评分细则，取指定范围内的得分
                        cRRDetailList.stream().forEach(cRRDetail -> {
                            //CRR率是否在本记录最小范围内
                            boolean isMinScope = false;
                            if("是".equals(cRRDetail.get("iscontainMIN"))){
                                if(rate.compareTo((BigDecimal) cRRDetail.get("MinScope")) >= 0){
                                    isMinScope = true;
                                }
                            }else {
                                if(rate.compareTo((BigDecimal) cRRDetail.get("MinScope")) > 0){
                                    isMinScope = true;
                                }
                            }
                            //CRR率是否在本记录最大范围内
                            boolean isMaxScope = false;
                            if("是".equals(cRRDetail.get("iscontainmax"))){
                                if(rate.compareTo((BigDecimal) cRRDetail.get("MaxScope")) <= 0){
                                    isMaxScope = true;
                                }
                            }else {
                                if(rate.compareTo((BigDecimal) cRRDetail.get("MaxScope")) < 0){
                                    isMaxScope = true;
                                }
                            }
                            if(isMinScope && isMaxScope){
                                //命中本记录，更新得分
                                item.put("CRRScore", cRRDetail.get("score"));
                            }
                        });
                    }
                });

                //按CRR率重新排名
                summaryList = summaryList.stream().sorted((objA, objB) -> {
                    // CRR率越高，排名越靠前
                    BigDecimal crrA = Optional.of((BigDecimal) objA.get("CRRRate")).orElse(BigDecimal.ZERO);
                    BigDecimal crrB = Optional.of((BigDecimal) objB.get("CRRRate")).orElse(BigDecimal.ZERO);
                    return crrA.compareTo(crrB) >= 0 ? -1 : 1;
                }).collect(Collectors.toList());

                //更新排名
                for (int i = 0; i < summaryList.size(); i ++){
                    //按顺序调整排名
                    Map<String, Object>map = summaryList.get(i);
                    map.put("CRRRanking", i + 1);

                    if(jxsCode.equals(map.get("Dealercode"))){
                        //更新子流程经销商排名
                        bizObject.getData().put("CRRRate", rate);
                        bizObject.getData().put("CRRRanking", i + 1);
                        bizObject.getData().put("CRRScore", map.get("CRRScore"));
                    }
                }
                break;
            case "EMI":
                //EMI率
                //更新主流程上经销商EMI率
                summaryList.stream().forEach(item -> {
                    String dealercode = (String) item.get("Dealercode");
                    if(StringUtils.isNotBlank(dealercode) && dealercode.equals(jxsCode)){
                        //更新EMI率
                        item.put("EMIRate", rate);
                        //获取评分细则
                        List<Map<String, Object>> cRRDetailList = (List<Map<String, Object>>)parentBizObjectModel.get("EMIdetail");
                        //更新得分，根据评分细则，取指定范围内的得分
                        cRRDetailList.stream().forEach(cRRDetail -> {
                            //EMI率是否在本记录最小范围内
                            boolean isMinScope = false;
                            if("是".equals(cRRDetail.get("iscontainmin"))){
                                if(rate.compareTo((BigDecimal) cRRDetail.get("minScope")) >= 0){
                                    isMinScope = true;
                                }
                            }else {
                                if(rate.compareTo((BigDecimal) cRRDetail.get("minScope")) > 0){
                                    isMinScope = true;
                                }
                            }
                            //EMI率是否在本记录最大范围内
                            boolean isMaxScope = false;
                            if("是".equals(cRRDetail.get("iscontainmax"))){
                                if(rate.compareTo((BigDecimal) cRRDetail.get("maxDate")) <= 0){
                                    isMaxScope = true;
                                }
                            }else {
                                if(rate.compareTo((BigDecimal) cRRDetail.get("maxDate")) < 0){
                                    isMaxScope = true;
                                }
                            }
                            if(isMinScope && isMaxScope){
                                //命中本记录，更新得分
                                item.put("EMIScore", cRRDetail.get("score"));
                            }
                        });
                    }
                });

                //按EMI率重新排名
                summaryList = summaryList.stream().sorted((objA, objB) -> {
                    // CRR率越高，排名越靠前
                    BigDecimal emiA = Optional.of((BigDecimal) objA.get("EMIRate")).orElse(BigDecimal.ZERO);
                    BigDecimal emiB = Optional.of((BigDecimal) objB.get("EMIRate")).orElse(BigDecimal.ZERO);
                    return emiA.compareTo(emiB) >= 0 ? -1 : 1;
                }).collect(Collectors.toList());

                //更新排名
                for (int i = 0; i < summaryList.size(); i ++){
                    //按顺序调整排名
                    Map<String, Object>map = summaryList.get(i);
                    map.put("EMIRanking", i + 1);

                    if(jxsCode.equals(map.get("Dealercode"))){
                        //更新子流程经销商排名
                        bizObject.getData().put("EMIRATE", rate);
                        bizObject.getData().put("EMIRanking", i + 1);
                        bizObject.getData().put("EMIScore", map.get("EMIScore"));
                    }
                }
                break;
        }

        //计算总得分和总排名
        countTotalScoreAndRank(summaryList);
        //更新子流程的总得分和排名
        for (int i = 0; i < summaryList.size(); i ++){
            Map<String, Object>map = summaryList.get(i);
            if(jxsCode.equals(map.get("Dealercode"))){
                //更新子流程经销商
                bizObject.getData().put("TotalScore", map.get("TotalScore"));
                bizObject.getData().put("Rank", map.get("Rank"));
            }
        }
    }
    //计算总得分和总排名
    private void countTotalScoreAndRank(List<Map<String, Object>> summaryList){
        if(summaryList != null){
            //计算总得分
            summaryList.stream().forEach(item -> {
                //累计4项得分
                BigDecimal CSVScore = Optional.of((BigDecimal) item.get("CSVScore")).orElse(BigDecimal.ZERO);
                BigDecimal PASScore = Optional.of((BigDecimal) item.get("PASScore")).orElse(BigDecimal.ZERO);
                BigDecimal CRRScore = Optional.of((BigDecimal) item.get("CRRScore")).orElse(BigDecimal.ZERO);
                BigDecimal EMIScore = Optional.of((BigDecimal) item.get("EMIScore")).orElse(BigDecimal.ZERO);
                item.put("TotalScore", CSVScore.add(PASScore).add(CRRScore).add(EMIScore));
            });
        }

        //按总得分重新排名
        summaryList = summaryList.stream().sorted((objA, objB) -> {
            // 总得分越高，排名越靠前
            BigDecimal totalA = Optional.of((BigDecimal) objA.get("TotalScore")).orElse(BigDecimal.ZERO);
            BigDecimal totalB = Optional.of((BigDecimal) objB.get("TotalScore")).orElse(BigDecimal.ZERO);
            return totalA.compareTo(totalB) >= 0 ? -1 : 1;
        }).collect(Collectors.toList());

        //更新排名
        for (int i = 0; i < summaryList.size(); i ++){
            //按顺序调整排名
            Map<String, Object>map = summaryList.get(i);
            map.put("Rank", i + 1);
        }

    }
}
